/*
 * @copyright: Huang Ding
 * @Author: ding-cx
 * @Date: 2021-03-09 17:38:43
 * @LastEditors: ding-cx
 * @LastEditTime: 2021-04-07 11:20:05
 * @Description: 学前端，不要继承event类。放在内部属性上。即可自定义emit，代理on。
 */

import { EggApplication } from "egg";
import * as EventEmitter from "events";
import { IPCData } from "../../ws";
import OnMessage from "./onMessage";

/**
 *封装事件类。在worker进程中实例化调用 
 其on接收agent发送过来的message并被分发。emit则发送推送消息出去。
 类似socket.io的基于事件的封装。
 *
 * @class WsWorker
 * @extends {EventEmitter}
 */

const initCacheState = Symbol("WsWorker#init");

class WsWorker {
  app: EggApplication;
  emitter: EventEmitter;
  constructor(app: EggApplication) {
    this.emitter = new EventEmitter();
    this.app = app;
  }

  /** 交给app手动init，监听插件内发送出的业务层事件。 */
  init() {
    if (this[initCacheState]) return this;
    this.onMessage();
    this.getPools();
    this[initCacheState] = true;
    return this;
  }

  private onMessage() {
    //   对应agent事件，接收消息
    this.app.messenger.on("ws-message", (msg: IPCData) => {
      // console.log(msg);
      // 转发给业务层事件监听
      this.emitter.emit(msg.event, new OnMessage(msg, this.app), msg);
    });
  }

  /** 监听onMessage触发的事件，进行业务逻辑处理 */
  on(event, callback) {
    this.emitter.on(event, callback);
  }

  /** 主动发送给前端，模拟事件触发方法。 */
  emit(
    event: string | symbol,
    uid: "*" | string | string[] = "*",
    data: any = {}
  ) {
    const msg = {
      event,
      wsuid: Array.isArray(uid) ? "" : uid,
      wsuids: Array.isArray(uid) ? uid : [],
    };
    if (uid === "*") {
      //全部发
      new OnMessage(msg, this.app).broadcast(data);
    } else if (Array.isArray(uid)) {
      //部分人群发
      new OnMessage(msg, this.app).send(uid, data);
    } else {
      //给某个人发
      new OnMessage(msg, this.app).send(uid, data);
    }
  }

  //   获取连接池的名单
  pools: string[] = [];
  private getPools() {
    this.app.messenger.on("ws-get-pools", (list) => {
      this.pools = list;
    });
  }
}

export default WsWorker;
